﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ImageK.Exceptions
{
    public static class RectangleExtensions
    {
        /**
         * Translates this {@code Rectangle} the indicated distance,
         * to the right along the X coordinate axis, and
         * downward along the Y coordinate axis.
         * @param dx the distance to move this {@code Rectangle}
         *                 along the X axis
         * @param dy the distance to move this {@code Rectangle}
         *                 along the Y axis
         * @see       java.awt.Rectangle#setLocation(int, int)
         * @see       java.awt.Rectangle#setLocation(java.awt.Point)
         */
        public static void translate(this Rectangle rect, int dx, int dy)
        {
            int oldv = rect.X;
            int newv = oldv + dx;
            if (dx < 0)
            {
                // moving leftward
                if (newv > oldv)
                {
                    // negative overflow
                    // Only adjust width if it was valid (>= 0).
                    if (rect.Width >= 0)
                    {
                        // The right edge is now conceptually at
                        // newv+width, but we may move newv to prevent
                        // overflow.  But we want the right edge to
                        // remain at its new location in spite of the
                        // clipping.  Think of the following adjustment
                        // conceptually the same as:
                        // width += newv; newv = MIN_VALUE; width -= newv;
                        rect.Width += newv - Int32.MinValue;
                        // width may go negative if the right edge went past
                        // MIN_VALUE, but it cannot overflow since it cannot
                        // have moved more than MIN_VALUE and any non-negative
                        // number + MIN_VALUE does not overflow.
                    }
                    newv = Int32.MinValue;;
                }
            }
            else
            {
                // moving rightward (or staying still)
                if (newv < oldv)
                {
                    // positive overflow
                    if (rect.Width >= 0)
                    {
                        // Conceptually the same as:
                        // width += newv; newv = MAX_VALUE; width -= newv;
                        rect.Width += newv - int.MaxValue;
                        // With large widths and large displacements
                        // we may overflow so we need to check it.
                        if (rect.Width < 0) rect.Width = int.MaxValue;
                    }
                    newv = int.MaxValue;
                }
            }
            rect.X = newv;

            oldv = rect.Y;
            newv = oldv + dy;
            if (dy < 0)
            {
                // moving upward
                if (newv > oldv)
                {
                    // negative overflow
                    if (rect.Height >= 0)
                    {
                        rect.Height += newv - int.MinValue;
                        // See above comment about no overflow in this case
                    }
                    newv = int.MinValue;
                }
            }
            else
            {
                // moving downward (or staying still)
                if (newv < oldv)
                {
                    // positive overflow
                    if (rect.Height >= 0)
                    {
                        rect.Height += newv - int.MaxValue;
                        if (rect.Height < 0) rect.Height = int.MaxValue;
                    }
                    newv = int.MaxValue;
                }
            }
            rect.Y = newv;
        }
    }
}
